package com.autorun.server.service;

import com.autorun.server.dto.ConfigRequest;
import com.autorun.server.entity.Config;
import com.autorun.server.entity.UserConfig;
import com.autorun.server.mapper.ConfigMapper;
import com.autorun.server.mapper.UserConfigMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 配置服务类
 * 
 * @author autorun
 * @version 1.0.0
 */
@Slf4j
@Service
public class ConfigService {

    @Autowired
    private ConfigMapper configMapper;

    @Autowired
    private UserConfigMapper userConfigMapper;

    /**
     * 创建配置
     * 
     * @param userId 用户ID
     * @param request 配置请求
     * @return 配置信息
     */
    @Transactional
    public Config createConfig(Integer userId, ConfigRequest request) {
        // 创建配置
        Config config = new Config();
        config.setName(request.getName());
        config.setGame(request.getGame());
        config.setContent(request.getContent());
        config.setDescription(request.getDescription());
        config.setVersion(1);
        config.setCreateTime(LocalDateTime.now());
        config.setUpdateTime(LocalDateTime.now());

        configMapper.insert(config);

        // 关联用户和配置
        UserConfig userConfig = new UserConfig();
        userConfig.setUserId(userId);
        userConfig.setConfigId(config.getId());
        userConfig.setCreateTime(LocalDateTime.now());

        userConfigMapper.insert(userConfig);

        log.info("创建配置成功 - ID: {}, 名称: {}", config.getId(), config.getName());
        return config;
    }

    /**
     * 根据ID获取配置
     * 
     * @param configId 配置ID
     * @return 配置信息
     */
    public Config getConfigById(Integer configId) {
        Config config = configMapper.selectById(configId);
        if (config == null) {
            throw new RuntimeException("配置不存在");
        }
        return config;
    }

    /**
     * 获取用户的所有配置
     * 
     * @param userId 用户ID
     * @return 配置列表
     */
    public List<Config> getUserConfigs(Integer userId) {
        return configMapper.findByUserId(userId);
    }

    /**
     * 更新配置
     * 
     * @param configId 配置ID
     * @param userId 用户ID
     * @param request 配置请求
     * @return 配置信息
     */
    @Transactional
    public Config updateConfig(Integer configId, Integer userId, ConfigRequest request) {
        // 检查用户是否拥有此配置
        if (!isUserOwnConfig(userId, configId)) {
            throw new RuntimeException("用户没有权限操作此配置");
        }

        Config config = getConfigById(configId);
        config.setName(request.getName());
        config.setContent(request.getContent());
        config.setDescription(request.getDescription());
        config.setVersion(config.getVersion() + 1);
        config.setUpdateTime(LocalDateTime.now());

        configMapper.updateById(config);

        log.info("更新配置成功 - ID: {}, 名称: {}", config.getId(), config.getName());
        return config;
    }

    /**
     * 删除配置
     * 
     * @param configId 配置ID
     * @param userId 用户ID
     */
    @Transactional
    public void deleteConfig(Integer configId, Integer userId) {
        // 检查用户是否拥有此配置
        if (!isUserOwnConfig(userId, configId)) {
            throw new RuntimeException("用户没有权限操作此配置");
        }

        // 删除用户配置关联
        userConfigMapper.deleteByConfigId(configId);

        // 删除配置
        configMapper.deleteById(configId);

        log.info("删除配置成功 - ID: {}", configId);
    }

    /**
     * 检查用户是否拥有配置
     * 
     * @param userId 用户ID
     * @param configId 配置ID
     * @return 是否拥有
     */
    public boolean isUserOwnConfig(Integer userId, Integer configId) {
        Integer count = configMapper.countUserConfig(userId, configId);
        return count != null && count > 0;
    }

    /**
     * 获取支持的游戏列表
     * 
     * @return 游戏列表
     */
    public List<String> getSupportedGames() {
        return Collections.singletonList("尤弥尔传奇国际服");
    }

    /**
     * 获取游戏配置模板
     * 
     * @param game 游戏名
     * @return 配置模板
     */
    public List<Map<String, Object>> getGameConfigTemplate(String game) {
        List<Map<String, Object>> templates = new ArrayList<>();

        if ("尤弥尔传奇国际服".equals(game)) {
            templates.add(createTemplateField("enable_main_quest", "boolean", "是否执行主线任务", 
                "控制是否自动执行主线剧情任务", true, true, 1));
            
            templates.add(createTemplateField("main_quest_level_limit", "number", "主线任务等级限制", 
                "主线任务执行到多少级停止", 50, false, 2));
            
            templates.add(createTemplateField("enable_world_boss", "boolean", "世界boss", 
                "控制是否参与世界boss战斗", true, false, 3));
            
            templates.add(createTemplateField("enable_daily_dungeon", "boolean", "每日副本", 
                "控制是否自动刷每日副本", true, false, 4));
            
            templates.add(createTemplateField("daily_dungeon_type", "select", "副本类型", 
                "选择要刷的每日副本类型", "经验屋(25级)", false, 5,
                Arrays.asList("经验屋(25级)", "经验屋(35级)", "琥珀屋(25级)", "琥珀屋(35级)")));
            
            templates.add(createTemplateField("daily_hang_map", "select", "日常挂机地图", 
                "选择日常挂机地图", "迷宫东1层(28级)", true, 8,
                Arrays.asList("迷宫东1层(28级)", "迷宫东2层(35级)", "迷宫东4层(40级)", 
                    "迷宫东4层(45级)", "迷宫西1层(35级)", "迷宫西2层(40级)", "迷宫西3层(45级)",
                    "挖矿开箱-雪地一层", "挖矿开箱-雪地二层", "琥珀-世界树二层")));
        }

        return templates;
    }

    /**
     * 创建模板字段
     */
    private Map<String, Object> createTemplateField(String fieldName, String fieldType, String fieldLabel, 
            String fieldDescription, Object defaultValue, boolean required, int sortOrder) {
        return createTemplateField(fieldName, fieldType, fieldLabel, fieldDescription, defaultValue, required, sortOrder, null);
    }

    /**
     * 创建模板字段（带选项）
     */
    private Map<String, Object> createTemplateField(String fieldName, String fieldType, String fieldLabel, 
            String fieldDescription, Object defaultValue, boolean required, int sortOrder, List<String> options) {
        Map<String, Object> template = new HashMap<>();
        template.put("field_name", fieldName);
        template.put("field_type", fieldType);
        template.put("field_label", fieldLabel);
        template.put("field_description", fieldDescription);
        template.put("default_value", defaultValue);
        template.put("required", required);
        template.put("sort_order", sortOrder);
        if (options != null) {
            template.put("field_options", options);
        }
        return template;
    }

    /**
     * 获取脚本端配置
     * 
     * @param configId 配置ID
     * @param clientVersion 客户端版本
     * @return 脚本配置响应
     */
    public Map<String, Object> getScriptConfig(Integer configId, Integer clientVersion) {
        Config config = getConfigById(configId);
        
        Map<String, Object> response = new HashMap<>();
        response.put("config_id", configId);
        response.put("version", config.getVersion());
        response.put("name", config.getName());
        response.put("game", config.getGame());
        response.put("updated", false);

        // 检查版本是否需要更新
        if (clientVersion == null || clientVersion == 0 || !clientVersion.equals(config.getVersion())) {
            response.put("updated", true);
            // 扁平化配置内容
            response.put("config", flattenConfig(config.getContent()));
        }

        return response;
    }

    /**
     * 将嵌套的JSON配置扁平化为KV结构
     */
    private Map<String, Object> flattenConfig(Map<String, Object> content) {
        Map<String, Object> result = new HashMap<>();

        for (Map.Entry<String, Object> entry : content.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            if (value instanceof Map) {
                // 如果是嵌套对象，将其键值对提取到一级
                @SuppressWarnings("unchecked")
                Map<String, Object> nestedMap = (Map<String, Object>) value;
                for (Map.Entry<String, Object> nestedEntry : nestedMap.entrySet()) {
                    String flatKey = key + "_" + nestedEntry.getKey();
                    result.put(flatKey, nestedEntry.getValue());
                }
            } else {
                // 直接的值类型
                result.put(key, value);
            }
        }

        return result;
    }
}